﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;


namespace RSSReader
{
  public partial class MainPage : PhoneApplicationPage
  {
    private Dictionary<string, Mainpage.FeedTile> mFeedTiles;
    private Mainpage.FeedTile mAllTile;
    private bool mIsBusy { get; set; }
    public MainPage()
    {
      InitializeComponent();
      mFeedTiles = new Dictionary<string, Mainpage.FeedTile>();
      App.SaveData = new SaveData();
      SortFeedsBox.IsChecked = App.SaveData.SortFeeds;
      KeepAlphabeticalBox.IsChecked = App.SaveData.AlphaFeeds;
      KeepAlphabeticalBox.IsEnabled = App.SaveData.SortFeeds;
      QueryOnStartupBox.IsChecked = App.SaveData.UnreadOnStartup;
      UnreadFeedsOnlyBox.IsChecked = App.SaveData.OnlyGetUnreadFeeds;
      FeedDownloadSlider.Value = App.SaveData.FeedsToDownload;
      FeedDownloadSlider.ValueChanged += onDownloadFeedsChanged;

      App.GReader = new GoogleReaderAPI();
      App.GReader.ReaderReady += onConnected;
      App.GReader.FeedListReady += onFeedListReady;
      App.GReader.UnreadListReady += onUnreadListReady;
      App.GReader.RefreshDone += onReaderRefreshDone;

      mAllTile = new Mainpage.FeedTile(1, "unknown", App.ALLITEMSNAME, 0);
      mAllTile.Container.Hold += onFeedHeld;

      mIsBusy = false;
    }

    private void busy()
    {
      ProgressGrid.Visibility = Visibility.Visible;
      //ProgressBar.IsIndeterminate = mIsBusy;
      mIsBusy = true;
    }

    private void ready()
    {
      ProgressGrid.Visibility = Visibility.Collapsed;
      //ProgressBar.IsIndeterminate = mIsBusy;
      mIsBusy = false;
    }

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
      base.OnNavigatedTo(e);
      ParameterizedUri p = new ParameterizedUri(e.Uri);
      // If there is no saved credentials data, ask for it first.
      if (App.SaveData.UserName.Equals("") && !p.hasParameter("usrn"))
      {
        NavigationService.Navigate(new Uri("/CredentialsPage.xaml", UriKind.Relative));
      }
      // If this page was navigated to with a connected=true variable, request feeds.
      else if (p.hasParameter("usrn"))
      {
        if (!App.GReader.IsReady)
        {
          mFeedTiles.Clear();
          App.GReader.UserName = p["usrn"];
          App.GReader.Password = p["pswd"];
          busy();
          App.GReader.connect();
        }
      }
      // If this page was navigated too with credentials stored, use them to connect to Google Reader.
      else
      {
        if (!App.GReader.IsReady)
        {
          mFeedTiles.Clear();
          App.GReader.UserName = App.SaveData.UserName;
          App.GReader.Password = App.SaveData.Password;
          busy();
          App.GReader.connect();
        }
      }
    }

    private void addAllItemsTile()
    {
      feedList.Items.Add(mAllTile.Container);
    }

    private void onConnected(Object sender, EventArgs e)
    {
      App.SaveData.UserName = App.GReader.UserName;
      App.SaveData.Password = App.GReader.Password;
      App.GReader.getFeedList();
    }

    private void onFeedListReady(Object source, GoogleReaderAPI.FeedListEventArgs e)
    {
      feedList.Items.Clear();
      foreach (GoogleReaderAPI.FeedListEventArgs.Feed f in e.Feeds)
      {
        if (f.FeedTitle.Equals(mAllTile.BaseName))
        {
          mAllTile.Url = f.FeedUrl;
          mAllTile.setTextOfCount(f.NewCount, 0, 0);
          e.Feeds.Remove(f);
          break;
        }
      }
      addAllItemsTile();
      foreach (GoogleReaderAPI.FeedListEventArgs.Feed f in e.Feeds)
      {
        addFeed(f.FeedUrl, f.FeedTitle, f.NewCount, e.MinUnread, e.UnreadRange);
      }
      ready();
    }

    private void onUnreadListReady(Object source, GoogleReaderAPI.UnreadListEventArgs e)
    {
      mAllTile.setTextOfCount(0, 0, 1);
      foreach (KeyValuePair<string, Mainpage.FeedTile> f in mFeedTiles)
      {
        f.Value.setTextOfCount(0, 0, 1);
      }

      foreach (GoogleReaderAPI.UnreadListEventArgs.UnreadFeed f in e.Feeds)
      {
        if (f.IsAllFeed)
        {
          mAllTile.Url = f.FeedUrl;
          mAllTile.setTextOfCount(f.NumUnread, 1, 0);
          SaveData.FeedInformation fi = new SaveData.FeedInformation(App.ALLITEMSNAME, f.FeedUrl, f.NumUnread);
          App.SaveData.updateFeed(fi);
        }
      }

      foreach (GoogleReaderAPI.UnreadListEventArgs.UnreadFeed f in e.Feeds)
      {
        SaveData.FeedInformation feed = App.SaveData.getFeedFromUrl(f.FeedUrl);
        if (feed != null)
        {
          Mainpage.FeedTile tile = (mFeedTiles.ContainsKey(f.FeedUrl) ? mFeedTiles[f.FeedUrl] : null);
          if (tile != null)
          {
            tile.setTextOfCount(f.NumUnread, e.MinUnread, e.UnreadRange);
          }
        }
      }
     sort();
    }

    private void onReaderRefreshDone(object sender, EventArgs e)
    {
      ready();
    }

    private void sort()
    {
      if (App.SaveData.SortFeeds)
      {
        // Put all feeds with unread items first.
        List<UIElement> unread = new List<UIElement>(), read = new List<UIElement>();
        foreach (KeyValuePair<string, SaveData.FeedInformation> feed in App.SaveData.Feeds)
        {
          //Debug.WriteLine(feed.Value.Url);
          Canvas c = FindName(feed.Value.Title + "_canvas") as Canvas;
          TextBlock b = FindName(feed.Value.Title + "_count") as TextBlock;
          if (c != null && b != null)
          {
            if (b.Text.Equals(""))
            {
              read.Add(c);
            }
            else
            {
              unread.Add(c);
            }
          }
        }
        foreach (UIElement i in read)
          unread.Add(i);
        feedList.Items.Clear();
        addAllItemsTile();
        foreach (Canvas c in unread)
        {
          feedList.Items.Add(c);
        }
      }
    }

    private void onAddFeedBtnClicked(object sender, EventArgs e)
    {
      if (!mIsBusy)
      {
        Debug.WriteLine("Adding a feed");
      }
    }

    private void onRefreshFeedBtnClicked(object sender, EventArgs e)
    {
      if (!mIsBusy)
      {
        busy();
        App.GReader.queryUnreadList();
      }
    }

    private void addFeed(string feedUrl, string feedTitle, int newCount, int min=0, int range=0)
    {
      Mainpage.FeedTile tile = new Mainpage.FeedTile(mFeedTiles.Count, feedUrl, feedTitle, newCount);
      feedList.Items.Add(tile.Container);
      tile.Container.Hold += onFeedHeld;
      mFeedTiles.Add(feedUrl, tile);
      tile.setTextOfCount(newCount, min, range);
    }

    private void onFeedHeld(Object sender, System.Windows.Input.GestureEventArgs e)
    {
      if (!mIsBusy)
      {
        Canvas tile = (Canvas)(sender);
        ShellTileData std = new StandardTileData
        {
          Title = "Szarko",
          BackContent = "8===D",
          Count = 50,
          BackTitle = "8====D"
        };

        ShellTile.Create(new Uri("/MainPage.xaml", UriKind.Relative), std);
        Debug.WriteLine("Tile held");
      }
    }

    private void onFeedListItemSelected(object sender, SelectionChangedEventArgs e)
    {
      if (e.AddedItems.Count == 1)
      {
        Canvas tile = e.AddedItems[0] as Canvas;
        Debug.WriteLine("{0} Selected", tile.Name);
        feedList.SelectedIndex = -1;
        if (!mIsBusy)
        {
          if (tile.Name.Equals(mAllTile.Container.Name))
          {
            ParameterizedUri p = new ParameterizedUri("/FeedPage.xaml");
            p["title"] = mAllTile.BaseName;
            this.NavigationService.Navigate(p.toURI());
          }
          else
          {
            foreach (KeyValuePair<string, Mainpage.FeedTile> feedTile in mFeedTiles)
            {
              if (feedTile.Value.Container.Name == tile.Name)
              {
                ParameterizedUri p = new ParameterizedUri("/FeedPage.xaml");
                p["title"] = feedTile.Value.BaseName;
                this.NavigationService.Navigate(p.toURI());
                break;
              }
            }
          }
        }
      }
    }

    private void onSortFeedsBoxChecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.SortFeeds = true;
      KeepAlphabeticalBox.IsEnabled = true;
    }

    private void onSortFeedsBoxUnchecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.SortFeeds = false;
      KeepAlphabeticalBox.IsChecked = false;
      KeepAlphabeticalBox.IsEnabled = false;
    }

    private void onKeepAlphabeticalBoxChecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.AlphaFeeds = true;
    }

    private void onKeepAlphabeticalBoxUnchecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.AlphaFeeds = false;
    }

    private void onQueryOnStartupBoxChecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.UnreadOnStartup = true;
    }

    private void onQueryOnStartupBoxUnchecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.UnreadOnStartup = false;
    }

    private void onUnreadFeedsOnlyBoxChecked(object sender, RoutedEventArgs e)
    {
      if (App.SaveData != null)
      {
        App.SaveData.OnlyGetUnreadFeeds = true;
      }
    }

    private void onUnreadFeedsOnlyBoxUnchecked(object sender, RoutedEventArgs e)
    {
      App.SaveData.OnlyGetUnreadFeeds = false;
    }

    private void onDownloadFeedsChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
      if (App.SaveData != null)
      {
        int val = (int)Math.Round(e.NewValue);
        Slider slider = (Slider)sender;
        slider.Value = val;
        App.SaveData.FeedsToDownload = val;
      }
    }

    private void onSettingsListSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      SettingsList.SelectedIndex = -1;
    }
  }
}